package com.site.blog.controller.job;


import com.github.pagehelper.PageInfo;
import com.site.blog.config.DbBackUpInfoConf;
import com.site.blog.constants.HttpStatusEnum;
import com.site.blog.dto.AjaxResultPage;
import com.site.blog.dto.Result;
import com.site.blog.entity.quartz.JobAndTrigger;
import com.site.blog.job.BaseJob;
import com.site.blog.service.IJobAndTriggerService;
import com.site.blog.util.ResultGenerator;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping(value = "/admin")
public class JobController {
    @Autowired
    private IJobAndTriggerService iJobAndTriggerService;

    @Autowired
    private DbBackUpInfoConf dbBackUpInfoConf;

    //加入Qulifier注解，通过名称注入bean
    @Autowired
    @Qualifier("Scheduler")
    private Scheduler scheduler;

    private static Logger log = LoggerFactory.getLogger(JobController.class);


    /**
     * 跳转到 定时任务控制列表
     *
     * @return
     */
    @GetMapping("/job")
    public String jobList() {
        return "adminLayui/job/job-list";
    }

    /**
     * 跳转到 定时任务修改,添加页面
     */
    @GetMapping("/job/add")
    public String jobEditOrSave(Integer jobId, Model model) {
        return "adminLayui/job/job-add";
    }

    /**
     * 添加定时任务
     *
     * @param jobClassName   任务类全类名
     * @param jobGroupName   分组名
     * @param cronExpression cron表达式
     */
    @PostMapping(value = "/addjob")
    @ResponseBody
    public Result<String> addjob(@RequestParam(value = "jobClassName") String jobClassName,
                                 @RequestParam(value = "jobGroupName") String jobGroupName,
                                 @RequestParam(value = "cronExpression") String cronExpression) throws Exception {
        boolean b = addJob(jobClassName, jobGroupName, cronExpression);
        if (b) {
            return ResultGenerator.getResultByHttp(HttpStatusEnum.OK);
        }
        return ResultGenerator.getResultByHttp(HttpStatusEnum.INTERNAL_SERVER_ERROR);
    }

    public boolean addJob(String jobClassName, String jobGroupName, String cronExpression) throws Exception {
        // 启动调度器
        scheduler.start();

        //构建job信息
        JobDetail jobDetail = JobBuilder.newJob(getClass(jobClassName).getClass()).withIdentity(jobClassName, jobGroupName).build();

        //表达式调度构建器(即任务执行的时间)
        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);

        //按新的cronExpression表达式构建一个新的trigger
        CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(jobClassName, jobGroupName)
                .withSchedule(scheduleBuilder).build();
        try {
            scheduler.scheduleJob(jobDetail, trigger);
            return true;
        } catch (SchedulerException e) {
            log.error("创建定时任务失败: {}", e);
        } finally {
            return false;
        }
    }

    /**
     * 暂停 定时任务
     */
    @PostMapping(value = "/pausejob")
    @ResponseBody
    public Result<String> pausejob(@RequestParam(value = "jobClassName") String jobClassName, @RequestParam(value = "jobGroupName") String jobGroupName) throws Exception {

        jobPause(jobClassName, jobGroupName);
        return ResultGenerator.getResultByHttp(HttpStatusEnum.OK);
    }

    public void jobPause(String jobClassName, String jobGroupName) throws Exception {
        scheduler.pauseJob(JobKey.jobKey(jobClassName, jobGroupName));
    }


    /**
     * 恢复定时任务
     */
    @PostMapping(value = "/resumejob")
    @ResponseBody
    public Result<String> resumejob(@RequestParam(value = "jobClassName") String jobClassName, @RequestParam(value = "jobGroupName") String jobGroupName) throws Exception {
        jobresume(jobClassName, jobGroupName);
        return ResultGenerator.getResultByHttp(HttpStatusEnum.OK);
    }

    public void jobresume(String jobClassName, String jobGroupName) throws Exception {
        scheduler.resumeJob(JobKey.jobKey(jobClassName, jobGroupName));
    }


    /**
     * 修改定时任务，cron表达式
     */
    @PostMapping(value = "/reschedulejob")
    @ResponseBody
    public Result<String> rescheduleJob(@RequestParam(value = "jobClassName") String jobClassName,
                                        @RequestParam(value = "jobGroupName") String jobGroupName,
                                        @RequestParam(value = "cronExpression") String cronExpression) throws Exception {
        boolean b = jobreschedule(jobClassName, jobGroupName, cronExpression);
        if (b) {
            return ResultGenerator.getResultByHttp(HttpStatusEnum.OK);
        }
        return ResultGenerator.getResultByHttp(HttpStatusEnum.INTERNAL_SERVER_ERROR);
    }

    public boolean jobreschedule(String jobClassName, String jobGroupName, String cronExpression) throws Exception {
        try {
            TriggerKey triggerKey = TriggerKey.triggerKey(jobClassName, jobGroupName);
            // 表达式调度构建器
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);

            CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);

            // 按新的cronExpression表达式重新构建trigger
            trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();

            // 按新的trigger重新设置job执行
            scheduler.rescheduleJob(triggerKey, trigger);
            return true;
        } catch (Exception e) {
            log.error("更新定时任务失败: {}", e);
        } finally {
            return false;
        }
    }


    /***
     *  删除定时任务
     */
    @PostMapping(value = "/deletejob")
    @ResponseBody
    public Result<String> deletejob(@RequestParam(value = "jobClassName") String jobClassName, @RequestParam(value = "jobGroupName") String jobGroupName) throws Exception {
        jobdelete(jobClassName, jobGroupName);
        return ResultGenerator.getResultByHttp(HttpStatusEnum.OK);
    }

    public void jobdelete(String jobClassName, String jobGroupName) throws Exception {
        scheduler.pauseTrigger(TriggerKey.triggerKey(jobClassName, jobGroupName));
        scheduler.unscheduleJob(TriggerKey.triggerKey(jobClassName, jobGroupName));
        scheduler.deleteJob(JobKey.jobKey(jobClassName, jobGroupName));
    }


    /**
     * 查询定时任务列表
     *
     * @param pageNum  页码
     * @param pageSize 每页大小
     */
    @GetMapping(value = "/job/list")
    @ResponseBody
    public AjaxResultPage<JobAndTrigger> queryjob(
            @RequestParam(value = "page") Integer pageNum, @RequestParam(value = "limit") Integer pageSize) {

        PageInfo<JobAndTrigger> pageInfo = iJobAndTriggerService.getJobAndTriggerDetails(pageNum, pageSize);
        Map<String, Object> map = new HashMap<String, Object>();

        AjaxResultPage<JobAndTrigger> result = new AjaxResultPage<>();
        List<JobAndTrigger> list = pageInfo.getList();
        long total = pageInfo.getTotal();
        result.setData(list);
        result.setCount(total);
        return result;
    }

    public static BaseJob getClass(String classname) throws Exception {
        Class<?> class1 = Class.forName(classname);
        return (BaseJob) class1.newInstance();
    }
}
